package xutils

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"math/rand"
	"strings"
	"time"

	"github.com/google/uuid"
)

var table = map[uint8][]byte{
	0: []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
	1: []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'},
	2: []byte{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'},
	3: []byte{'!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '|', '~'},
}

func init() {
	// 开启uuid的随机池,提高uuid吞吐量
	uuid.EnableRandPool()
}

func CalculateRemainder(b byte, r uint8) uint8 {
	return uint8(b) % r
}

func GetByte(key, value uint8) byte {
	switch CalculateRemainder(key, 4) {
	case 0:
		return table[0][CalculateRemainder(value, 10)]
	case 1:
		return table[1][CalculateRemainder(value, 26)]
	case 2:
		return table[2][CalculateRemainder(value, 26)]
	case 3:
		return table[3][CalculateRemainder(value, 26)]
	default:
		return '-'
	}
}

func RandomUUID() (string, error) {
	uid, err := uuid.NewRandom()
	return uid.String(), err
}

// 生成验证码
func RandomCaptcha(length int) (string, error) {
	uuid, err := uuid.NewRandom()
	if err != nil {
		return "", err
	}
	// 将随机字节转换为0-9之间的数字
	var strBuilder strings.Builder
	for i := 0; i < length; i++ {
		strBuilder.WriteByte(GetByte(0, uuid[i]))
	}
	return strBuilder.String(), nil
}

func RandomString(length int) (string, error) {
	uuid, err := uuid.NewRandom()
	if err != nil {
		return "", err
	}

	if len(uuid) < length*2 {
		return "", fmt.Errorf("超过了随机数的长度")
	}

	var strBuilder strings.Builder
	for i := 0; i < length*2; i += 2 {
		strBuilder.WriteByte(GetByte(uuid[i], uuid[i+1]))
	}
	return strBuilder.String(), nil
}

func MD5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

func GenerateOrderId() string {
	// 获取当前时间
	now := time.Now()
	// 格式化时间为 "YYYYMMDDHHMMSS" 格式
	timestamp := now.Format("20060102150405") + fmt.Sprintf("%03d", now.Nanosecond()%1000000/1000)
	// 生成一个三位随机数
	random := rand.Intn(999)
	// 组合成完整的订单号
	orderId := fmt.Sprintf("%s%03d", timestamp, random)
	return orderId
}
